#include "SudokuDataModel.h"

int SudokuDataModel::ContextMenuRole = Qt::UserRole + 1;

SudokuDataModel::SudokuDataModel(SudokuData* _sudokuData, QObject *parent) : QAbstractTableModel(parent),
sudokuData(_sudokuData)
{
}

SudokuDataModel::~SudokuDataModel()
{
    if(sudokuData)
    {
        delete sudokuData;
        sudokuData = 0;
    }
}

int SudokuDataModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return sudokuData->getSize();
}

int SudokuDataModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return sudokuData->getSize();
}

QVariant SudokuDataModel::data(const QModelIndex &index, int role) const
{
    //qDebug() << "SudokuDataModel::data";
    if (role == Qt::DisplayRole)
    {
       return sudokuData->cellAt(index.row(), index.column())->getValue();
    }
    else if(role == Qt::EditRole)
    {
        if(sudokuData->cellAt(index.row(), index.column())->isEmpty())
            return QString("");
        else
            return sudokuData->cellAt(index.row(), index.column())->getValue();
    }
    else if(role == ContextMenuRole)
    {
        if(sudokuData->cellAt(index.row(), index.column())->isEmpty())
        {
            QList<QVariant> variantList;
            QList<int> candidateList = sudokuData->cellAt(index.row(), index.column())->getCandidateList();
            for(int i =0; i<candidateList.size(); ++i)
            {
                variantList.append(candidateList.at(i));
            }

            return variantList;
        }
        else
        {
            return QVariant();
        }
    }

    //TODO for testing:
    return QString("@");//QVariant();
}


Qt::ItemFlags SudokuDataModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return Qt::ItemIsEnabled;

    if(sudokuData->cellAt(index.row(), index.column())->isGiven())
        return Qt::NoItemFlags;

    return Qt::ItemIsEditable | Qt::ItemIsEnabled;
}

bool SudokuDataModel::setData(const QModelIndex &index,
                              const QVariant &value, int role)
{
    bool ok = false;
    if (index.isValid() && role == Qt::EditRole)
    {
        QString stringValue = value.toString();
        if(stringValue.isEmpty())
        {
            ok = sudokuData->setCellValue(index.row(), index.column(), 0, Empty);
            if(ok)
            {
                emit dataChanged(index, index);
            }
        }
        else
        {
            int cellValue = stringValue.toInt(&ok);

            if(ok)
            {
                ok = sudokuData->setCellValue(index.row(), index.column(), cellValue, User);
                if(ok)
                {
                    emit dataChanged(index, index);
                }
            }
        }
    }
    return ok;
}

void SudokuDataModel::setSudokuData(SudokuData* data)
{
    qDebug() << "SudokuDataModel::setSudokuData !!!";

    if(sudokuData)
        delete sudokuData;
    sudokuData = data;

    bool connectOk = connect(sudokuData, SIGNAL(valueFound(int, int, int, CellFillerTypes)),
            this, SLOT(onCellChanged(int,int)));
    Q_ASSERT(connectOk);

    connectOk = connect(sudokuData, SIGNAL(possiblExcluded(int, int, int, CellFillerTypes)),
            this, SLOT(onCellChanged(int,int)));
    Q_ASSERT(connectOk);
}

SudokuData* SudokuDataModel::getSudokuData() const
{
    return sudokuData;
}

void SudokuDataModel::clear()
{
    if(sudokuData)
        sudokuData->clear();
}

void SudokuDataModel::onCellChanged(int row, int col)
{
    qDebug() << "SudokuDataModel::onCellChanged row " << row << " col " << col;
    QModelIndex cellIndex = index(row, col);
    emit dataChanged(cellIndex, cellIndex);
}

